﻿using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

using Tszy.Unlimited.Base.Exceptions;
using Tszy.Unlimited.Data.AdoNet.Sql.Components.Expressions.Values;

namespace Tszy.Unlimited.Data.AdoNet.Sql.Components.Expressions.Filters
{
    /// <summary>
    /// 实现 linq 中的 SELECT 函数。
    /// </summary>
    internal class SelectExpressionExecutor : ExpressionExecutorBase
    {
        /// <summary>
        /// 初始化。
        /// </summary>
        public SelectExpressionExecutor() : base(ExpressionKey.SELECT)
        {
        }

        /// <summary>
        /// 执行。
        /// </summary>
        /// <param name="context">上下文。</param>
        /// <param name="expression">表达式。</param>
        /// <returns>结果。</returns>
        public override ExpressionExecutorResult Execute(ExpressionContext context, Expression expression)
        {
            if (expression == null)
                throw new MainApplicationException("Select 函数处理失败，表达式不可以是 null。");

            context.Fields.AddRange(ExecuteHandler(context, expression));

            return new ExpressionExecutorResult { Status = true };
        }

        private static List<ExpressionParameter> ExecuteHandler(ExpressionContext context, Expression expression)
        {
            var sqlFields = new List<ExpressionParameter>();

            var lambdaExpression = expression as LambdaExpression;

            var members = ValueExpressionHandler.Handler(context, lambdaExpression?.Body);

            if (members.Value is IEnumerable<ExpressionParameter> fields && fields.Any())
            {
                sqlFields.AddRange(fields);
            }
            else
            {
                if (members.Value != null)
                {
                    var parameterName = $"{members.Value}";

                    sqlFields.Add(new ExpressionParameter { Name = parameterName });
                }
            }

            return sqlFields;
        }
    }
}